package com.lechi.web.util;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * FTP功能类
 */
@Slf4j
@Component
public class FtpUtil {

    @Getter
    @Value("${ftp.watch.path}")
    private String filePath;

    @Value("${ftp.host}")
    private String host;

    @Value("${ftp.port}")
    private Integer port;

    @Value("${ftp.username}")
    private String username;

    @Value("${ftp.password}")
    private String password;

    /**
     * Delete directory boolean.
     *
     * @param client  the client
     * @param dirPath the dir path
     * @return the boolean
     * @throws IOException the io exception
     */
    public boolean deleteDirectory(FTPClient client, String dirPath) throws IOException {
        boolean isDeleted = true;
        FTPFile[] fileList = client.listFiles(dirPath);
        if (fileList != null) {
            for (FTPFile file : fileList) {
                if (file.isFile()) {
                    isDeleted = client.deleteFile(dirPath + "/" + file.getName());
                    if (!isDeleted) {
                        break;
                    }
                } else if (file.isDirectory()) {
                    boolean delResult = deleteDirectory(client, dirPath + "/" + file.getName());
                    if (!delResult) {
                        break;
                    }
                    isDeleted = client.removeDirectory(dirPath + "/" + file.getName());
                    if (!isDeleted) {
                        break;
                    }
                }
            }
        }
        isDeleted = client.removeDirectory(dirPath);
        return isDeleted;
    }

    /**
     * Delete file to ftp.
     *
     * @param ftpFilePath the ftp file path
     */
    public void deleteFileToFtp(String ftpFilePath) {
        FTPClient ftp = connectFtpServer();
        try {
            assert ftp != null;
            if (ftp.isConnected()) {
                deleteDirectory(ftp, this.filePath + "/" + ftpFilePath);
                ftp.logout();
            }
        } catch (Exception e) {
            log.error("FTP文件删除失败", e);
        } finally {
            assert ftp != null;
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    log.error(ioe.toString());
                }
            }
        }
    }

    private FTPClient connectFtpServer() {
        // 创建FTPClient对象（对于连接ftp服务器，以及上传和上传都必须要用到一个对象）
        FTPClient ftpClient = new FTPClient();
        // 设置连接超时时间
        ftpClient.setConnectTimeout(1000 * 60);
        // 设置ftp字符集
        ftpClient.setControlEncoding("utf-8");
        // 设置被动模式，文件传输端口设置,否则文件上传不成功，也不报错
        ftpClient.enterLocalPassiveMode();
        // 定义返回的状态码
        int replyCode = 0;
        try {
            // 连接ftp(当前项目所部署的服务器和ftp服务器之间可以相互通讯，表示连接成功)
            ftpClient.connect(host, port);
            // 输入账号和密码进行登录
            ftpClient.login(username, password);
            // 接受状态码(如果成功，返回230，如果失败返回503)
            replyCode = ftpClient.getReplyCode();
            // 根据状态码检测ftp的连接，调用isPositiveCompletion(reply)-->如果连接成功返回true，否则返回false
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                log.info("connect ftp {} failed", host);
                // 连接失败，断开连接
                ftpClient.disconnect();
                return null;
            }
            log.info("replyCode:" + replyCode);
        } catch (IOException e) {
            log.error("connect fail:" + e);
            return null;
        }
        return ftpClient;
    }

}
